﻿using System;
using System.Drawing;
using UnityEngine;
using UnityEngine.UIElements;
using Color = UnityEngine.Color;

namespace winS.UnityEditor.UIElement
{
    /// <summary>
    /// Button (Editor only).
    /// Supports image and text.
    /// </summary>
    public class Button : EditorControl
    {
        private const float defaultMultiple = 1.2f;
        private const float defaultAnimationDuration = 0.1f;

        public static readonly Color defaultNormalColor = ColorLevelUtility.GetColor(8);
        public static readonly Color defaultHighlightColor = defaultNormalColor * defaultMultiple;

        public event Action onClick;

        public string text { get => _label?.text; set => SetLabel(value); }

        /// <summary>
        /// 按钮颜色
        /// </summary>
        public virtual Color normalColor { get => _normalColor; set => SetNormalColor(value); }
        /// <summary>
        /// 按钮颜色(悬浮时)
        /// </summary>
        public virtual Color highlightColor { get => _highlightColor; set => SetHighlightColor(value); }

        public string labelText { get => label.text; set => SetLabel(value); }

        public Icon icon => _icon ??= EditorElementUtility.elementFactory.CreateIcon();
        public Label label => _label ??= EditorElementUtility.elementFactory.CreateLabel();
        public Texture texture { get => icon.image; set => SetTexture(value); }

        private bool highlighting;

        private Color _normalColor = defaultNormalColor;
        private Color _highlightColor = defaultHighlightColor;

        private Icon _icon;
        private Label _label;

        internal Button(ElementFactory elementFactory) : base(elementFactory)
        {
            style.alignItems = Align.Center;
            style.overflow = Overflow.Hidden;
            style.justifyContent = Justify.Center;
            style.flexDirection = FlexDirection.Row;

            style.SetVerticalPadding(1f);
            style.SetHorizontalPadding(4f);
            InitializeStyle();

            RegisterCallback<MouseEnterEvent>(MouseEnterCallback);
            RegisterCallback<MouseLeaveEvent>(MouseLeaveCallback);
            EditorElementUtility.RegisterClickEvent(this, () => onClick?.Invoke());
        }

        public void Click()
        {
            onClick?.Invoke();
        }
        public void SetLabel(string text)
        {
            label.text = text;
            Insert(childCount > 0 ? 1 : 0, label);
            if (_icon != null) icon.style.marginRight = icon.style.marginRight.value.value + elementFactory.marginHorizontal;
        }
        public void SetImageSize(float size)
        {
            SetImageSize(size, size);
        }
        public void SetImageSize(Vector2 size)
        {
            SetImageSize(size.x, size.y);
        }
        public void SetImageSize(float width, float height)
        {
            icon.SetSize(width, height);
        }
        public void SetTexture(Texture texture)
        {
            icon.image = texture;
            Insert(0, icon);
            if (!string.IsNullOrEmpty(label.text)) icon.style.marginRight = icon.style.marginRight.value.value + elementFactory.marginHorizontal;
        }
        public void SetTexture(Texture texture, Color tintColor)
        {
            SetTexture(texture);
            icon.tintColor = tintColor;
        }
        public void SetTexture(Texture texture, float size)
        {
            SetTexture(texture, size, size);
        }
        public void SetTexture(Texture texture, float size, Color tintColor)
        {
            SetTexture(texture, size, size, tintColor);
        }
        public void SetTexture(Texture texture, float width, float height)
        {
            SetTexture(texture);
            SetImageSize(width, height);
        }
        public void SetTexture(Texture texture, float width, float height, Color tintColor)
        {
            SetTexture(texture, width, height);
            icon.tintColor = tintColor;
        }
        public void SetColor(Color normalColor, Color highlightColor)
        {
            this.normalColor = normalColor;
            this.highlightColor = highlightColor;
        }
        public void SetColor(Color normalColor, float highlisthMultiple = defaultMultiple)
        {
            this.normalColor = normalColor;
            highlightColor = normalColor * highlisthMultiple;
        }

        protected virtual void InitializeStyle()
        {
            style.SetBorderRadius(2f);
            style.SetBorder(elementFactory.borderColor, 1f);
            style.SetBackgroundColor(normalColor);
            style.SetTransition("background-color", defaultAnimationDuration);
        }
        protected virtual void SetNormalColor(Color newNormalColor)
        {
            _normalColor = newNormalColor;
            if (highlighting) return;
            style.SetBackgroundColor(newNormalColor);
        }
        protected virtual void SetHighlightColor(Color newHighlightColor)
        {
            _highlightColor = newHighlightColor;
            if (!highlighting) return;
            style.SetBackgroundColor(newHighlightColor);
        }
        protected virtual void MouseEnterCallback(MouseEnterEvent mouseEnterEvent)
        {
            highlighting = true;
            style.SetBackgroundColor(highlightColor);
        }
        protected virtual void MouseLeaveCallback(MouseLeaveEvent mouseLeaveEvent)
        {
            highlighting = false;
            style.SetBackgroundColor(normalColor);
        }
    }
}